API网关和服务网格的区别
嘉宾文章最初由Kong联合创始人兼首席技术官Marco Palladino在Kong的博客上发表
为什么API管理和服务网格是不同用例的互补模式
注意:本文的目标是提供一个备忘单(Cheat sheet),指导架构师决定何时使用API网关,何时使用服务网格。如果你想直接进入“备忘单”部分,请跳到最后。
多年来,API管理(API Management,APIM)--以及API网关的采用--是用于在数据中心内外实现现代API用例的主要技术。API网关技术在过去十年中有了很大的发展,在业界所谓的“全生命周期API管理”中获得了更大、更全面的用例。不仅是运行时在请求的数据平面上连接、保护和管理我们的API流量,而且还具有一系列功能,可以在更广泛的范围内创建、测试、文档化、收费、监控和全面暴露API--并从头到尾针对更广泛的用户角色。也就是说,这里存在一个完整的生命周期,即创建API并将其作为产品提供给用户和客户,而不仅仅是网络运行时的管理,这使我们能够暴露和使用API(不管是否使用RESTful)。
然后在2017年左右,行业出现了另一种模式:服务网格。几乎立刻,业界就没能认识到这种模式是如何与API网关模式相互作用的,于是一团混乱开始出现。这在一定程度上是由于现有APIM供应商完全缺乏思想领导力,他们未能对服务网格如何补充现有APIM用例做出充分的响应。部分原因是主要的云供应商(首先由Google,后来由亚马逊,最后由Microsoft)开始将服务网格推向更广泛的行业,其速度如此之快,以致于开发人员对这种新模式的营销影响力早于主流用户的实际采用,因此在行业中产生了误解服务网格是什么(开发人员营销),和不是什么(技术实现)。几乎是每个人都在谈论的一种神秘模式,但很少有人掌握。
随着时间的推移,技术实现赶上了服务网格的最初设想,越来越多的用户实现了该模式并讲述了他们的故事。这使我们现在可以对什么是服务网格(什么不是)以及API网关(和APIM)在服务网格视图中的作用有一个更严肃的合理化。
许多人已经尝试了描述API网关和服务网格之间的区别,通常认为API网关用于南北通信量,服务网格用于东西通信量。这是不准确的,它强调了对这两种模式的基本误解。
在这篇文章中,我想说明API网关和服务网格之间的区别,以及什么时候以一种务实和客观的方式使用它们。
API网关
API网关模式描述了网络中的一个额外跃点,每个请求都必须经过这个跃点才能使用底层API。在这种情况下,有些人将API网关称为集中式部署。
API网关位于每个API请求的执行路径上,它是一个数据平面,接收来自客户端的请求,并在将这些请求反向代理到底层API之前执行流量和用户策略。在将请求代理回客户端之前,它还可以(而且很可能会)对从底层API接收到的响应执行策略。
API网关既可以具有内置的控制平面来管理和配置数据平面的功能,也可以将数据平面和控制平面都捆绑在一起,形成同一进程。尽管拥有一个单独的控制平面肯定会更好,但是某些API网关实现能够在同一过程中与DP+CP捆绑软件一起发展,因为我们将要部署的API网关节点的数量通常具有可管理的大小,并且可以使用现有的CI/CD流水线传播更新。
API网关部署在它自己的实例中(它自己的VM、主机或pod),独立于客户端和API。因此,部署非常简单,因为它完全独立于系统的其余部分,并且完全活在自己的架构层中。
API网关通常覆盖三个主要的API用例,用于内部和外部服务连接,以及南北(数据中心外部)和东西(数据中心内部)通信流。
1. API作为产品
第一个用例是关于将API打包为其他开发人员、合作伙伴或团队将使用的产品。
他们构建的客户端应用程序可以从组织外部(例如移动应用程序)或同一公司内部(例如另一个产品,可能由另一个团队或另一条业务线构建)发起请求。无论哪种方式,客户端应用程序都将运行在它们所使用的产品(即暴露的API)的范围之外。
当将API作为产品提供时,API网关将封装管理从客户端到API服务的请求的公共需求--例如,AuthN/AuthZ用例、速率限制、开发人员入职、收费或客户端应用程序治理。这些是由L7用户策略实现的高级用例,它们超越了底层协议的管理,因为它们控制用户将如何使用API产品。
API网关暴露的API很可能是运行在HTTP协议上的(即REST、SOAP、GraphQL或gRPC),根据客户端应用程序是在数据中心内部运行还是在数据中心外部运行,流量可以是南北向的,也可以是东西向的。一个移动应用程序将主要运行到API网关的南北通信量,而组织内的另一个产品,如果它部署在与其使用的API相同的数据中心中,可能运行东西通信量。流量的方向根本无关紧要。
API网关还用作一个抽象层,允许我们随时更改底层API,而不必更新使用它们的客户端。对于那些由组织外的开发人员构建的客户端应用程序,当我们每次决定更新它们时,都不能被迫更新到最强大和最新的API的场景,这一点尤其重要。在这种情况下,可以使用API网关来保持与那些客户端应用程序的向后兼容性,因为我们的底层API会随着时间的变化而变化。
2. 服务连接性
第二个用例是关于实施网络策略来连接、保护、加密、保护和观察客户端和API网关之间的网络流量,以及API网关和API之间的网络流量。它们可以被称为L7流量策略,因为它们对底层网络流量进行操作,而不是控制用户体验。
一旦API网关处理了请求,网关本身就必须向底层API发出请求以获得响应(毕竟,网关是反向代理)。通常,我们希望通过相互TLS保护请求,记录请求,并全面保护和观察网络通信。网关还充当负载均衡器,将实现HTTP路由等功能,支持将请求代理到我们的API的不同版本(在此上下文中,它还可以支持蓝/绿和灰度部署用例),以及故障注入等。
我们通过API网关暴露的底层API可以构建在任何架构(单体或微服务)中,因为只要API网关暴露了一个可消费的接口,它就不会假定这些API是如何构建的。API很可能暴露了一个可通过HTTP使用的接口(即REST、SOAP、GraphQL或gRPC)。
3. 全生命周期API管理
API网关的第三个用例是更广泛的API管理环境中的一个更大的难题。
我们都知道,在运行时管理API、它们的用户和客户端应用程序以及它们的流量只是运行一个成功的API策略所涉及的许多步骤中的一部分。必须创建、记录、测试和模拟这些API。API一旦运行,就必须对其进行监视和观察,以检测其使用中的异常情况。此外,在将API作为产品提供时,API将必须为最终用户提供一个门户,以便注册其应用程序、检索凭据并开始使用API。
这更广泛的体验,是端到端的、触动API的不同生命周期(通常不同的用户角色将负责不同部分的生命周期),被称为全生命周期API管理,大多数APIM解决方案都在一个或多个产品提供一个捆绑的解决方案来实现上述所有问题,将连接到API网关执行策略。
服务网格
通过服务网格,我们正在识别一种模式,从根本上改进了在系统中运行的两个或多个服务之间构建服务到服务连接性的方式。每当一个服务希望向另一个服务发出一个网络请求(例如,一个使用数据库的实体或一个使用另一个微服务的微服务),我们都希望通过使其更安全、更可观察等方法来处理该网络请求。
服务网格作为一种模式可以应用于任何架构(即单体或微服务),以及在任何平台上(例如:VM、容器、Kubernetes)。
在这方面,服务网格没有引入新的用例,但是它更好地实现了我们在引入服务网格之前已经必须管理的现有用例。甚至在实现服务网格之前,应用程序团队就已经在应用程序中实现了诸如安全性、可观察性和错误处理等流量策略,这样他们就可以增强应用程序发出或接收的任何出站(或入站)网络请求的连接性。应用程序团队通过在他们的服务中编写更多的代码来实现这些用例。这意味着不同的团队将一次又一次地重新实现相同的功能--并且使用不同的编程语言,为组织在管理网络连接时创建碎片和安全风险。
在服务网格之前,团队编写和维护代码来管理到第三方服务的网络连接。将存在不同的实现来支持不同的语言/框架。
使用服务网格模式,我们将任何服务(不仅是我们构建的服务,而且包括部署了的第三方服务)发出的任何入站或出站请求的网络管理外包到进程外应用程序(即代理),它将为我们管理每个入站和出站网络请求,并且由于它位于服务之外,因此默认情况下它是可移植且无感的,以便支持以任何语言或框架编写的任何服务。代理将位于每个请求的执行路径上,因此它是一个数据平面过程,并且由于其中一种用例正在实现端到端mTLS加密和可观察性,因此我们将在每个服务旁边运行一个代理实例 这样我们就可以无缝地实现这些功能,而无需应用程序团队做过多的工作并使这些关注点抽象化。
我们在每个服务实例旁边运行一个代理实例(紫色)。
由于数据平面代理将与每个服务的每个副本一起运行,因此有些人将服务网格称为分散部署(与集中式部署的API网关模式相反)。此外,由于我们将在网络中有额外的跃点,为了将延迟保持在最小,我们将在与我们正在运行的服务相同的机器(VM、主机、pod)上运行数据平面代理。理想情况下,如果代理的好处足够有价值,而延迟足够低,那么在组织管理服务之间的网络连接时,仍然会倾向于使用代理,而不是创建碎片。
代理应用程序在请求发出时充当代理,在请求传入时充当反向代理。因为我们将为每个服务副本运行代理应用程序的一个实例,所以我们的系统中将运行许多代理。为了对它们进行配置,我们需要一个控制平面,它作为我们想要执行的配置和行为的真实来源,并且连接到代理来动态地传播配置。因为控制平面只连接到代理,所以它不在服务到服务请求的执行路径上。
因此,服务网格模式比API网关模式更具侵入性,因为它要求我们在每个服务的每个实例旁边部署一个数据平面代理,要求我们在部署应用程序时大量更新CI/CD作业。虽然服务网格还有其他的部署模式,但是上面描述的模式(每个服务副本一个代理)被认为是行业标准,因为它保证了最好的、最高的可用性,并允许我们为每个服务的每个副本分配一个唯一的身份(通过一个mTLS证书)。
使用服务网格,我们基本上是在处理一个主要用例。
1. 服务连接性
通过将网络管理外包给第三方代理应用程序,团队可以避免在自己的服务中实现网络管理。然后,代理可以为我们部署的每个服务和工作负载实现诸如相互TLS加密、身份、路由、日志记录、跟踪、负载平衡等功能,包括我们的组织正在采用但不是从头开始构建的数据库等第三方服务。
由于组织内的服务连接性将在大量协议上运行,因此完整的服务网格实现理想情况下不仅支持HTTP,而且还支持任何其他TCP流量,无论它是南北还是东西走向。在这种情况下,服务网格支持更广泛的服务,并实现L4/L7流量策略,而API网关历来只关注L7策略。
从概念上看,服务网格对系统中运行的工作负载有一个非常简单的视图:一切都是一个服务,服务之间可以相互通信。因为API网关也是接收请求和发出请求的服务,所以API网关只是一个网格中其他服务中的一个服务。
由于每个服务的每个副本都需要在其旁边有一个数据平面代理,并且数据平面代理实际上是客户端负载平衡器,因此它们可以将传出的请求路由到其他代理(以及其他服务),因此服务网格的控制平面必须知道每个代理的地址,以便可以执行L4/L7路由功能。该地址可以与任何元数据相关联,例如服务名称。这样一来,服务网格实质上就可以提供内置的服务发现功能,而不一定需要第三方解决方案。服务发现工具仍可用于在网格外部进行通信,但很可能不会用于在网格内部进行的通信。
API网关vs.服务网格
通过查看用例可以清楚地看到,在API网关和服务网格之间有一个重叠区域,这就是服务连接性用例。
服务网格提供的服务连接性功能与API网关提供的API连接性功能相冲突。但是,由于服务网格提供的服务更具有包容性(L4+L7,所有的TCP流量,不仅仅是HTTP,不仅仅局限于API,而是每一个服务),所以它们在某种程度上更完整。但是,正如我们从上面的图表中可以看到的,服务网格也有不提供的用例,即“API作为产品”用例以及完整的API管理生命周期,它们仍然属于API网关模式。
由于服务网格为更广泛的用例(L4+L7)提供了所有的服务连接性需求,所以很自然地,我们会认为它会从API网关(仅L7)那里接管这些关注点。这个结论只有在我们能够利用服务网格部署模型的情况下才有效,正如我们将要探讨的,情况并不总是如此。
这两种模式之间的一个主要不同点实际上是部署模型:在一个服务网格模式中,我们必须在每个服务的每个副本旁边部署一个代理数据平面。当一个团队想要在自己的产品范围内或者自己的业务范围内部署服务网格时,这很容易做到,但是当我们想要在这个范围之外部署代理时,实现起来就比较困难了,原因有三:
将代理应用程序部署到组织中每个产品的每个服务旁边可能会遇到阻力,因为不同的产品、团队和业务线可能有根本不同的方法来构建、运行和部署它们的软件。
每个数据平面代理必须发起一个连接到控制平面,和在某些情况下,我们不希望--或者我们不能--授权访问服务部署的控制平面的边界之外的产品、团队或组织内的业务。
在每个服务旁边部署代理数据平面是不可能的,因为我们首先不能控制所有的服务,就像在第三方应用程序的情况下,由开发人员、客户或组织外部的合作伙伴构建。
部署在相同服务网格中的服务必须使用相同的CA(证书颁发机构)才能获得有效的TLS证书,以便相互使用,而在属于不同产品或团队的服务之间共享CA可能是不可能的,也不可取。在这种情况下,可以创建两个独立的服务网格(每个服务网格都有自己的CA),它们可以通过中间API网关相互通信。
鉴于API网关和服务网格关注不同的使用情况,我建议以下备忘单确定何时使用API网关和何时使用服务网格,这假设在大多数组织中都将因为使用用例(产品/用户用例和服务连接性)而必须实现的。
备忘单
我们将使用API网关,通过一个集中的入口点向内部或外部客户/用户提供“作为产品”的API,并通过一个完整生命周期的APIM平台来管理和控制这些API的暴露和上线方式。还用于在客户端和底层API之间创建抽象层。
我们将使用服务网格在你的系统中运行的所有服务之间建立可靠、安全和可观察的L4/L7流量连接,这是通过一个分散的边车部署模型实现的,可以在每个服务上采用和实施。用于在所有服务之间创建点对点连接。
最有可能的是,组织将同时拥有这两个用例,因此将同时使用API网关和服务网格。
例子:一家金融机构
根据上面的图表,我们可以提供以下示例。
对于一个组织来说,由不同的团队构建不同的产品是很常见的,这些产品必须相互通信(例如,一家金融机构将有一个执行银行活动的“银行产品”和一个允许股票市场交易的“交易产品”,但这两个产品必须通过通信来共享信息)。
这些团队还将在路线图中的某一点上决定实现服务网格,以改进组成最终产品的服务之间的服务连接性。因为不同的团队以不同的速度运行,他们将实现两个彼此隔离的服务网格:“服务网格A”和“服务网格B”。
让我们假设为了获得高可用性,这两个产品都部署在两个不同的数据中心“DC1”和“DC2”上。
银行团队希望将其服务作为产品提供给内部客户,即交易团队。因此,他们希望在适当的地方设置策略,就像团队是通过内部API网关的外部用户一样。移动团队也必须消费这两种产品,他们必须通过边缘API网关入口才能做到这一点。架构应该是这样的:
请注意,API网关也是网格的一部分,否则它们就没有身份(TLS证书)来允许它们在各自的网格中使用服务。正如我们已经讨论过的,API网关只是可以发出和接收网络请求的服务中的另一个服务。
点击【阅读原文】阅读英文原文。
扫描二维码联系我们!
CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux Foundation,是非营利性组织。
CNCF(云原生计算基金会)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。请长按以下二维码进行关注。